using System;

namespace CodeConsult.Nordic.nRF8001.ApplicationControlInterface.Commands
{
    public class EncodeHelper
    {
        public enum ByteOrder
        {
            LsbMsb,
            MsbLsb
        }

        private byte[] _buffer;
        private int _index;

        public bool Error { get; private set; }

        public byte[] Buffer
        {
            get { return _buffer; }
            set
            {
                _buffer = value;
                _index = 0;
                Error = false;
            }
        }

        internal EncodeHelper()
        {
        }

        public void SetByte(byte value)
        {
            if (CheckLength(sizeof(byte)))
            {
                Buffer[_index] = value;
               _index++;
            }
            else
            {
                Buffer[_index] = default(byte);
            }
        }

        public void SetUnsignedShort(ushort value, ByteOrder byteOrder)
        {
            if (!CheckLength(sizeof(ushort))) return;

            var bytes = BitConverter.GetBytes(value);
            SetBytes(bytes);

            if (byteOrder == ByteOrder.LsbMsb) return;

            Swap(_index - 2, 2);
        }

        public void SetBytes(byte[] value)
        {
            if (value == null || value.Length <= 0) return;

            if (!CheckLength(value.Length)) return;

            Array.Copy(value, 0, Buffer, _index, value.Length);
            _index += value.Length;
        }

        private bool CheckLength(int size)
        {
            if (Error) return !Error; // do NOT re-evaluate error

            Error = Buffer.Length < _index + size;

            return !Error;
        }

        private void Swap(int index, int numberOfBytes)
        {
            while (numberOfBytes >= 2)
            {
                var backup = Buffer[index];
                Buffer[index] = Buffer[index + numberOfBytes - 1];
                Buffer[index + numberOfBytes - 1] = backup;

                index = index + 1;
                numberOfBytes = numberOfBytes - 2;
            }
        }
    }
}
